<?php
/**
 *
 * @since   2021-11-01
 * @author  zhaoxiang <zhaoxiang051405@gmail.com>
 */

namespace EasyTiktok\Kernel;

use EasyTiktok\Kernel\Clauses\Platform;
use EasyTiktok\Kernel\Providers\ConfigServiceProvider;
use EasyTiktok\Kernel\Providers\EventDispatcherServiceProvider;
use EasyTiktok\Kernel\Providers\HttpClientServiceProvider;
use Pimple\Container;

class ServiceContainer extends Container {
    /**
     * @var string
     */
    protected string $id;

    /**
     * @var array
     */
    protected array $providers = [];

    /**
     * @var array
     */
    protected array $defaultConfig = [];

    /**
     * @var array
     */
    protected array $userConfig = [];

    /**
     * Constructor.
     *
     * @param array $config
     * @param array $prepends
     * @param string|null $id
     */
    public function __construct(array $config = [], array $prepends = [], string $id = '') {
        $this->userConfig = $config;
        parent::__construct($prepends);
        $this->registerProviders($this->getProviders());
        $this->id = $id;
    }

    /**
     * @return string
     */
    public function getId(): string {
        return $this->id ?? $this->id = md5(json_encode($this->userConfig));
    }

    /**
     * @return array
     */
    public function getConfig(): array {
        $base = [
            'http' => [
                'timeout' => 30.0
            ]
        ];

        if (empty($this->userConfig['platform_id'])) {
            $this->userConfig['platform_id'] = Platform::PLATFORM_TIKTOK;
        }

        switch ($this->userConfig['platform_id']) {
            case Platform::PLATFORM_TIKTOK:
                $base['base_url'] = 'https://open.douyin.com/';     // 抖音
                break;
            case Platform::PLATFORM_TOUTIAO:
                $base['base_url'] = 'https://open.snssdk.com/';     // 头条
                break;
            case Platform::PLATFORM_XIGUA:
                $base['base_url'] = 'https://open-api.ixigua.com/';  // 西瓜
                break;
        }

        return array_replace_recursive($base, $this->defaultConfig, $this->userConfig);
    }

    /**
     * Return all providers.
     *
     * @return array
     */
    public function getProviders(): array {
        return array_merge([
            ConfigServiceProvider::class,
            HttpClientServiceProvider::class,
            EventDispatcherServiceProvider::class,
        ], $this->providers);
    }

    /**
     * @param string $id
     * @param mixed $value
     */
    public function rebind(string $id, $value): void {
        $this->offsetUnset($id);
        $this->offsetSet($id, $value);
    }

    /**
     * Magic get access.
     *
     * @param string $id
     *
     * @return mixed
     */
    public function __get(string $id) {
        return $this->offsetGet($id);
    }

    /**
     * Magic set access.
     *
     * @param string $id
     * @param mixed $value
     */
    public function __set(string $id, $value) {
        $this->offsetSet($id, $value);
    }

    /**
     * Just For ide
     * @param string $id
     * @author zhaoxiang <zhaoxiang051405@gmail.com>
     */
    public function __isset(string $id) {

    }

    /**
     *
     * @param array $providers
     * @author zhaoxiang <zhaoxiang051405@gmail.com>
     */
    public function registerProviders(array $providers): void {
        foreach ($providers as $provider) {
            $this->register(new $provider());
        }
    }
}